package com.xbongbong.paas.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasAttachmentEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.NodeTypeEnum;
import com.xbongbong.paas.enums.PaySheetTypeEnum;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.exception.WorkflowException;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.pojo.ProcessNodeTaskLogMidPojo;
import com.xbongbong.paas.pojo.ProcessNodeTaskLogPoJo;
import com.xbongbong.paas.pojo.workflow.settings.WorkflowNodeConditionTypeEnum;
import com.xbongbong.paas.pojo.workflow.task.dto.WorkflowCommentListDTO;
import com.xbongbong.paas.pojo.workflow.task.dto.WorkflowNodeTaskGetDTO;
import com.xbongbong.paas.pojo.workflow.task.vo.WorkflowCommentListVO;
import com.xbongbong.paas.pojo.workflow.task.vo.WorkflowNodeTaskGetVO;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.workflow.comment.WorkflowCommentService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.WorkflowUtil;
import com.xbongbong.paas.util.WorkflowValidateUtil;
import com.xbongbong.parent.field.FieldAnalyseService;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.workflow.WorkflowSystemFieldEnum;
import com.xbongbong.pro.enums.workflow.WorkflowValueTypeEnum;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.FundTransferEntity;
import com.xbongbong.saas.domain.entity.OtherExpenseEntity;
import com.xbongbong.saas.domain.entity.OtherIncomeEntity;
import com.xbongbong.saas.domain.entity.WorkOrderEntity;
import com.xbongbong.saas.domain.entity.competitor.CompetitorEntity;
import com.xbongbong.saas.domain.entity.ext.AssembleEntityExt;
import com.xbongbong.saas.domain.entity.ext.BomBillEntityExt;
import com.xbongbong.saas.domain.entity.ext.ClueEntityExt;
import com.xbongbong.saas.domain.entity.ext.CommunicatePlanEntityExt;
import com.xbongbong.saas.domain.entity.ext.ContactEntityExt;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.CostAdjustEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerCommunicateEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.domain.entity.ext.InstockEntityExt;
import com.xbongbong.saas.domain.entity.ext.InventoryEntityExt;
import com.xbongbong.saas.domain.entity.ext.InvoiceEntityExt;
import com.xbongbong.saas.domain.entity.ext.MarketActivityEntityExt;
import com.xbongbong.saas.domain.entity.ext.OpportunityEntityExt;
import com.xbongbong.saas.domain.entity.ext.OutstockEntityExt;
import com.xbongbong.saas.domain.entity.ext.PayPlanEntityExt;
import com.xbongbong.saas.domain.entity.ext.PayPlanSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.ProductionOrderEntityExt;
import com.xbongbong.saas.domain.entity.ext.PurchaseEntityExt;
import com.xbongbong.saas.domain.entity.ext.PurchaseInvoiceEntityExt;
import com.xbongbong.saas.domain.entity.ext.QuotationEntityExt;
import com.xbongbong.saas.domain.entity.ext.RefundEntityExt;
import com.xbongbong.saas.domain.entity.ext.ReturnedPurchaseEntityExt;
import com.xbongbong.saas.domain.entity.ext.SupplierCommunicateEntityExt;
import com.xbongbong.saas.domain.entity.ext.SupplierContactEntityExt;
import com.xbongbong.saas.domain.entity.ext.SupplierEntityExt;
import com.xbongbong.saas.domain.entity.ext.TransferEntityExt;
import com.xbongbong.saas.domain.entity.ext.WarehouseEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkReportEntityExt;
import com.xbongbong.saas.enums.BusinessCommentEnum;
import com.xbongbong.saas.enums.SignTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.AssembleModel;
import com.xbongbong.saas.model.BomBillModel;
import com.xbongbong.saas.model.ClueModel;
import com.xbongbong.saas.model.CommunicatePlanModel;
import com.xbongbong.saas.model.CompetitorModel;
import com.xbongbong.saas.model.ContactModel;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.CostAdjustModel;
import com.xbongbong.saas.model.CustomerCommunicateModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.FundTransferModel;
import com.xbongbong.saas.model.InstockModel;
import com.xbongbong.saas.model.InventoryModel;
import com.xbongbong.saas.model.InvoiceModel;
import com.xbongbong.saas.model.MarketActivityModel;
import com.xbongbong.saas.model.OpportunityModel;
import com.xbongbong.saas.model.OtherExpenseModel;
import com.xbongbong.saas.model.OtherIncomeModel;
import com.xbongbong.saas.model.OutstockModel;
import com.xbongbong.saas.model.PaasFormDataModel;
import com.xbongbong.saas.model.PayPlanModel;
import com.xbongbong.saas.model.PayPlanSheetModel;
import com.xbongbong.saas.model.PaymentModel;
import com.xbongbong.saas.model.PaymentSheetModel;
import com.xbongbong.saas.model.ProductionOrderModel;
import com.xbongbong.saas.model.PurchaseInvoiceModel;
import com.xbongbong.saas.model.PurchaseModel;
import com.xbongbong.saas.model.QuotationModel;
import com.xbongbong.saas.model.RefundModel;
import com.xbongbong.saas.model.ReturnedPurchaseModel;
import com.xbongbong.saas.model.SupplierCommunicateModel;
import com.xbongbong.saas.model.SupplierContactModel;
import com.xbongbong.saas.model.SupplierModel;
import com.xbongbong.saas.model.TransferModel;
import com.xbongbong.saas.model.WarehouseModel;
import com.xbongbong.saas.model.WorkOrderModel;
import com.xbongbong.saas.model.WorkReportModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.workflow.domain.entity.WorkflowBackupDataEntity;
import com.xbongbong.workflow.domain.entity.WorkflowNodeEntity;
import com.xbongbong.workflow.domain.entity.ext.WorkflowCommentEntityExt;
import com.xbongbong.workflow.domain.entity.ext.WorkflowTaskNodeEntityExt;
import com.xbongbong.workflow.enums.WorkflowNodeTypeEnum;
import com.xbongbong.workflow.model.WorkflowBackupDataModel;
import com.xbongbong.workflow.model.WorkflowNodeModel;
import com.xbongbong.workflow.model.impl.WorkflowTaskModelImpl;
import com.xbongbong.workflow.pojo.Data;
import com.xbongbong.workflow.pojo.FlowData;
import com.xbongbong.workflow.pojo.FlowDatas;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.pojo.nodes.ConditionNode;
import com.xbongbong.workflow.pojo.nodes.WorkflowConditionFilters;
import com.xbongbong.workflow.pojo.nodes.WorkflowConditionPojo;
import com.xbongbong.workflow.pojo.nodes.WorkflowJointConditionPojo;
import com.xbongbong.workflow.pojo.nodes.WorkflowTitlePojo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 工作流流转help
 * @author 魏荣杰
 *
 */
@Slf4j
@Component
public class WorkflowHelp {

    @Resource
    private WorkflowNodeModel workflowNodeModel;
    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private ContactModel contactModel;
    @Resource
    private OutstockModel outstockModel;
    @Resource
    private OpportunityModel opportunityModel;
    @Resource
    private WorkReportModel workReportModel;
    @Resource
    private CommunicatePlanModel communicatePlanModel;
    @Resource
    private BomBillModel bomBillModel;
    @Resource
    private CustomerCommunicateModel customerCommunicateModel;
    @Resource
    private SupplierCommunicateModel supplierCommunicateModel;
    @Resource
    private ReturnedPurchaseModel returnedPurchaseModel;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private InventoryModel inventoryModel;
    @Resource
    private TransferModel transferModel;
    @Resource
    private WarehouseModel warehouseModel;
    @Resource
    private SupplierModel supplierModel;
    @Resource
    private SupplierContactModel supplierContactModel;
    @Resource
    private PurchaseModel purchaseModel;
    @Resource
    private ProductionOrderModel productionOrderModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private InvoiceModel invoiceModel;
    @Resource
    private PayPlanModel payPlanModel;
    @Resource
    private PaymentModel paymentModel;
    @Resource
    private AssembleModel assembleModel;
    @Resource
    private InstockModel instockModel;
    @Resource
    private RefundModel refundModel;
    @Resource
    private PaymentSheetModel paymentSheetModel;
    @Resource
    private WorkOrderModel workOrderModel;
    @Resource
    private QuotationModel quotationModel;
    @Resource
    private PayPlanSheetModel payPlanSheetModel;
    @Resource
    private PurchaseInvoiceModel purchaseInvoiceModel;
    @Resource
    private ClueModel clueModel;
    @Resource
    private MarketActivityModel marketActivityModel;
    @Resource
    private PaasFormDataModel paasFormDataModel;
    @Resource
    private CompareValueByConditionHelp compareValueByConditionHelp;
    @Resource
    private Map<Integer, FieldAnalyseService> fieldAnalyseMap;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private FundTransferModel fundTransferModel;
    @Resource
    private OtherIncomeModel otherIncomeModel;
    @Resource
    private OtherExpenseModel otherExpenseModel;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private CostAdjustModel costAdjustModel;
    @Resource
    private UserModel userModel;
    @Resource
    private WorkflowCommentService workflowCommentService;
    @Resource
    private WorkflowTaskModelImpl workflowTaskModel;
    @Resource
    private WorkflowNodeHelp workflowNodeHelp;
    @Resource
    private WorkflowBackupDataModel workflowBackupDataModel;
    @Resource
    private CompetitorModel competitorModel;
    @Resource
    private FormDataHelp formDataHelp;

    /**
     * Description: 传给下一个节点
     *
     * @param workflowTransferPOJO 流转的数据
     * @param workflowNodeEntity   当前流转到的节点
     * @return void
     * @throws
     * @author 魏荣杰
     * @date 2021/5/10 14:47
     */
    public WorkflowNodeEntity deliverToNextNode(WorkflowTransferPOJO workflowTransferPOJO, WorkflowNodeEntity workflowNodeEntity) throws WorkflowException {
        Map<String, Object> params = new HashMap<>();
        params.put(ParameterConstant.CORPID, workflowNodeEntity.getCorpid());
//        params.put(ParameterConstant.APPID, workflowNodeEntity.getAppId());
//        params.put(ParameterConstant.FORMID, workflowNodeEntity.getFormId());
//        params.put(ParameterConstant.MENUID, workflowNodeEntity.getMenuId());
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        params.put("prevId", workflowNodeEntity.getUid());
        params.put("workflowId", workflowNodeEntity.getWorkflowId());
        params.put(ParameterConstant.ORDER_BY_STR, " priority " + SortOrder.ASC);

        List<WorkflowNodeEntity> workflowNodeEntities = workflowNodeModel.findEntitys(params);
        if (workflowNodeEntities.isEmpty()) {
            //条件块包条件块情况
            if (Objects.isNull(workflowNodeEntity.getWrapperId())) {
                // 如果没有wrapperid就是普通节点，下面就没有了，直接返回null结束
                return null;
            }
            params.put("prevId", workflowNodeEntity.getWrapperId());
            params.put("typeNotIn", Collections.singletonList(WorkflowNodeTypeEnum.CONDITION_NODE.getType()));
            // 查找整个条件块下节点
            List<WorkflowNodeEntity> nodeList = workflowNodeModel.findEntitys(params);
            if (nodeList.isEmpty()) {
                params.remove("prevId");
                params.remove("typeNotIn");
                params.put("uid", workflowNodeEntity.getWrapperId());
                List<WorkflowNodeEntity> entitys = workflowNodeModel.findEntitys(params);
                if (!entitys.isEmpty()) {
                    return deliverToNextNodeForWrapper(entitys.get(0));
                }
            } else {
                WorkflowNodeEntity nodeEntity = nodeList.get(0);
                if (Objects.equals(nodeEntity.getType(), WorkflowNodeTypeEnum.CONDITION_BLOCK_NODE.getType())) {
//                    return deliverToNextNode(workflowTransferPOJO, workflowNodeEntity);
                    return nodeEntity;
                } else {
//                    String nodeTypeNameByType = WorkflowNodeTypeEnum.getNodeTypeNameByType(nodeEntity.getType());
//                    WorkflowNodeStrategy workflowNodeStrategy = workflowNodeStrategyMap.get(nodeTypeNameByType);
//                    workflowNodeStrategy.createTaskNode(workflowTransferPOJO, nodeEntity, workflowNodeEntity.getId());
                    return nodeEntity;
                }
            }

        } else {
            if (Objects.equals(workflowNodeEntity.getType(), WorkflowNodeTypeEnum.CONDITION_BLOCK_NODE.getType())) {
                // 条件块节点
                workflowNodeEntities.removeIf(item -> !Objects.equals(item.getType(), WorkflowNodeTypeEnum.CONDITION_NODE.getType()));
                // 判断条件节点，是否有满足条件的节点
                WorkflowNodeEntity nodeEntity = matchCondition(workflowTransferPOJO, workflowNodeEntities, workflowNodeEntity);
                if (Objects.nonNull(nodeEntity)) {
                    // 匹配到节点，生成相应节点任务
//                    String nodeTypeNameByType = WorkflowNodeTypeEnum.getNodeTypeNameByType(nodeEntity.getType());
//                    WorkflowNodeStrategy workflowNodeStrategy = workflowNodeStrategyMap.get(nodeTypeNameByType);
//                    workflowNodeStrategy.createTaskNode(workflowTransferPOJO, nodeEntity, workflowNodeEntity.getId());
                    return nodeEntity;
                }

            } else {
                // 其他节点，只有一个子节点
                if (workflowNodeEntities.size() > 1) {
                    throw new WorkflowException(MessageConstant.PROCESS_NODE_SET_ABNORMAL);
                }
                WorkflowNodeEntity nodeEntity = workflowNodeEntities.get(0);
                if (Objects.equals(nodeEntity.getType(), WorkflowNodeTypeEnum.CONDITION_BLOCK_NODE.getType())) {
//                    return deliverToNextNode(workflowTransferPOJO, nodeEntity);
                    return nodeEntity;
                } else {
                    // 生成相应节点
//                    String nodeTypeNameByType = WorkflowNodeTypeEnum.getNodeTypeNameByType(nodeEntity.getType());
//                    WorkflowNodeStrategy workflowNodeStrategy = workflowNodeStrategyMap.get(nodeTypeNameByType);
//                    workflowNodeStrategy.createTaskNode(workflowTransferPOJO, nodeEntity, workflowNodeEntity.getId());
                    return nodeEntity;
                }
            }
        }

        return null;
    }

    private WorkflowNodeEntity deliverToNextNodeForWrapper(WorkflowNodeEntity workflowNodeEntity) {
        if (Objects.isNull(workflowNodeEntity.getWrapperId())) {
            // 如果没有wrapperid就是普通节点，下面就没有了，直接返回null结束
            return null;
        }
        Map<String, Object> params = new HashMap<>();
        params.put(ParameterConstant.CORPID, workflowNodeEntity.getCorpid());
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        params.put(ParameterConstant.ORDER_BY_STR, " priority " + SortOrder.ASC);
        params.put("prevId", workflowNodeEntity.getWrapperId());
        params.put("typeNotIn", Collections.singletonList(WorkflowNodeTypeEnum.CONDITION_NODE.getType()));
        params.put("workflowId", workflowNodeEntity.getWorkflowId());
        // 查找整个条件块下节点
        List<WorkflowNodeEntity> nodeList = workflowNodeModel.findEntitys(params);
        if (nodeList.isEmpty()) {
            params.remove("prevId");
            params.remove("typeNotIn");
            params.put("uid", workflowNodeEntity.getWrapperId());
            List<WorkflowNodeEntity> entitys = workflowNodeModel.findEntitys(params);
            if (!entitys.isEmpty()) {
                return deliverToNextNodeForWrapper(entitys.get(0));
            }
        } else {
            return nodeList.get(0);
        }
        return null;
    }

    /**
     * Description: 匹配分支
     *
     * @param workflowNodeEntities
     * @return com.xbongbong.workflow.domain.entity.WorkflowNodeEntity
     * @throws
     * @author 魏荣杰
     * @date 2021/5/11 16:16
     * @since
     */
    private WorkflowNodeEntity matchCondition(WorkflowTransferPOJO workflowTransferPOJO, List<WorkflowNodeEntity> workflowNodeEntities, WorkflowNodeEntity workflowNodeEntity) throws WorkflowException {
        WorkflowNodeEntity matchNode = null;
        WorkflowNodeEntity elseNode = null;
        try {
            boolean hasElse = false;
            boolean match = false;
            for (WorkflowNodeEntity nodeEntity : workflowNodeEntities) {
                ConditionNode conditionNode = workflowNodeHelp.getConditionNode(nodeEntity);
                if (Objects.equals(conditionNode.getConditionType(), WorkflowNodeConditionTypeEnum.ELSE_TYPE.getType())) {
                    hasElse = true;
                    elseNode = nodeEntity;
                    continue;
                }
                if (Objects.equals(conditionNode.getConditionType(), WorkflowNodeConditionTypeEnum.HAS_DATA.getType())) {
                    // 有数据
                    WorkflowNodeEntity hasDataConditionNode = workflowNodeModel.getByUId(workflowNodeEntity.getWorkflowId(), workflowNodeEntity.getCorpid(), workflowNodeEntity.getPrevId());
                    FlowDatas flowDatas = workflowTransferPOJO.getFlowDatas();
                    flowDatas = flowDatas == null ? new FlowDatas() : flowDatas;
                    Map<String, FlowData> nodeIdMap = flowDatas.getNodeIdMap();
                    nodeIdMap = nodeIdMap == null ? new HashMap<>(BasicConstant.ONE) : nodeIdMap;
                    FlowData flowData = nodeIdMap.get(hasDataConditionNode.getId().toString());
                    if (CollectionUtils.isNotEmpty(flowData.getIds())) {
                        matchNode =  nodeEntity;
                        match = true;
                        break;
                    }
                }
                if (Objects.equals(conditionNode.getConditionType(), WorkflowNodeConditionTypeEnum.NONE_DATA.getType())) {
                    // 无数据
                    WorkflowNodeEntity noDataConditionNode = workflowNodeModel.getByUId(workflowNodeEntity.getWorkflowId(), workflowNodeEntity.getCorpid(), workflowNodeEntity.getPrevId());
                    FlowDatas flowDatas = workflowTransferPOJO.getFlowDatas();
                    flowDatas = flowDatas == null ? new FlowDatas() : flowDatas;
                    Map<String, FlowData> nodeIdMap = flowDatas.getNodeIdMap();
                    nodeIdMap = nodeIdMap == null ? new HashMap<>(BasicConstant.ONE) : nodeIdMap;
                    FlowData flowData = nodeIdMap.get(noDataConditionNode.getId().toString());
                    if (CollectionUtils.isEmpty(flowData.getIds())) {
                        matchNode =  nodeEntity;
                        match = true;
                        break;
                    }
                }

                if (Objects.equals(conditionNode.getConditionType(),WorkflowNodeConditionTypeEnum.APPROVAL_PAAS.getType())) {
                    // 审批通过
                    if (Objects.isNull(workflowTransferPOJO.getRefuseFlag()) || !workflowTransferPOJO.getRefuseFlag()) {
                        matchNode = nodeEntity;
                        match = true;
                        break;
                    }
                }

                if (Objects.equals(conditionNode.getConditionType(), WorkflowNodeConditionTypeEnum.APPROVAL_REFUSE.getType())) {
                    // 审批拒绝
                    if (Objects.nonNull(workflowTransferPOJO.getRefuseFlag()) && workflowTransferPOJO.getRefuseFlag()) {
                        matchNode = nodeEntity;
                        match = true;
                        break;
                    }
                }

                if (Objects.equals(conditionNode.getConditionType(), WorkflowNodeConditionTypeEnum.NORMAL_TYPE.getType())) {
                    WorkflowJointConditionPojo conditions = conditionNode.getConditions();
                    if (Objects.isNull(conditions) || CollectionsUtil.isEmpty(conditions.getFilters())) {
                        // 当条件为null，走这条
                        matchNode =  nodeEntity;
                        match = true;
                        break;
                    } else {
                        Data data = JSON.parseObject(JSON.toJSONString(workflowTransferPOJO.getData(), SerializerFeature.DisableCircularReferenceDetect), Data.class);
                        if (Objects.equals(0, conditionNode.getEditedData()) && WorkflowOperateEnum.updateOperateList().contains(workflowTransferPOJO.getOperate())) {
                            data = JSON.parseObject(JSON.toJSONString(workflowTransferPOJO.getOldData(), SerializerFeature.DisableCircularReferenceDetect), Data.class);
                        } else if (Objects.equals(2, conditionNode.getEditedData()) && WorkflowOperateEnum.updateOperateList().contains(workflowTransferPOJO.getOperate())) {
                            // 触发事件编辑前数据
                            if (Objects.equals(WorkflowOperateEnum.UPDATE_BATCH.getType(), workflowTransferPOJO.getOperate())) {
                                // 批量编辑时backup_data表中无数据，oldData即最原始的数据
                                data = JSON.parseObject(JSON.toJSONString(workflowTransferPOJO.getOldData(), SerializerFeature.DisableCircularReferenceDetect), Data.class);
                            } else {
                                WorkflowBackupDataEntity workflowBackupDataEntity = workflowBackupDataModel.getByKey(workflowTransferPOJO.getBackupDataId(), workflowTransferPOJO.getCorpid());
                                data.setData(workflowBackupDataEntity.getData());
                            }

                        }
                        JSONObject dataObj = data.getData();

                        // 当前配置都是外面为或，条件组内且
                        List<WorkflowConditionFilters> filters = conditions.getFilters();
                        match = false;
                        if (CollectionsUtil.isNotEmpty(filters)) {
                            for (WorkflowConditionFilters filter : filters) {
                                match = isMatch(workflowTransferPOJO, nodeEntity, dataObj, filter);

                                if (match) {
                                    break;
                                }
                            }

                        }

                    }
                }
                // 所有条件都满足
                if (match) {
                    matchNode = nodeEntity;
                    break;
                }
            }
            if (match) {
                // 满足条件
                return matchNode;
            } else if (hasElse) {
                // 当所有条件不满足，但是有else时，走此流程
                return elseNode;
            } else {
                // 所有条件不满足
                return null;
            }
        } catch (Exception e) {
            log.error("com.xbongbong.paas.help.WorkflowHelp.matchCondition error", e);
            throw new WorkflowException(SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 条件匹配
     * @author 魏荣杰
     *
     */
    private boolean isMatch(WorkflowTransferPOJO workflowTransferPOJO, WorkflowNodeEntity nodeEntity, JSONObject dataObj, WorkflowConditionFilters filter) throws Exception {
        List<WorkflowConditionPojo> filterFilter = filter.getFilter();
        boolean match = false;
        for (WorkflowConditionPojo condition : filterFilter) {
            match = false;
            String attr = condition.getAttr();
            Object value = null;
            if (Objects.equals(attr, FieldTypeEnum.UPDATETIME.getAlias())) {
                value = DateTimeUtil.getInt();
            } else if (Objects.equals(attr, FieldTypeEnum.ADDTIME.getAlias())) {
                value = DateTimeUtil.getInt();
            } else if (Objects.equals(condition.getTriggerNodeFlag(), BasicConstant.ONE)) {
                // TODO 现在默认是触发节点，不可以选择其他节点
                value = dataObj.get(attr);
            }

            if (Objects.equals(attr, "creator_dept")) {
                if (Objects.nonNull(workflowTransferPOJO.getUser())) {
                    List<Object> conditionValue = condition.getValue();
                    Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    StringBuilder depIdInRegexp = new StringBuilder();
                    for (int i = 0; i < conditionValue.size(); i++) {
                        String router = Objects.toString(conditionValue.get(i), "0");
                        if (StringUtil.isNotEmpty(router)) {
                            depIdInRegexp.append("(\\|").append(router).append("\\|)");
                            if (i != conditionValue.size() - 1) {
                                depIdInRegexp.append("|");
                            }
                        }
                    }
                    param.put("del", 0);
                    param.put("corpid", nodeEntity.getCorpid());
                    /*
                     * 数据库内dep_id_router字段的数值格式为：|1|2|4|
                     * 如果想获取部门id为1、2的部门的所有子部门，则等于获取dep_id_router所有包含"|1|"或"|2|"的
                     */
                    param.put("routerRegexp", depIdInRegexp.toString());
                    List<Long> perList = departmentModel.getDepIds(param);
                    UserEntity userEntity = userModel.getByKeyIngoreDel(workflowTransferPOJO.getUser().getUserId(), nodeEntity.getCorpid());
                    String dept = userEntity.getDepartment();
                    JSONArray deptArray = JSON.parseArray(dept);
                    for (int i = 0; i < deptArray.size(); i++) {
                        Long router = deptArray.getLong(i);
                        if (perList.contains(router)) {
                            match = true;
                            break;
                        }
                    }
                }
            } else {
                // 校验条件和值是否匹配
                // TODO: 2021/5/12
                match = compareValue(condition, value);
            }

            if (!match) {
                break;
            }
        }
        return match;
    }

    /**
     * 比较数据
     * @param workflowConditionPojo
     * @param value
     * @return
     * @throws Exception
     */
    private boolean compareValue(WorkflowConditionPojo workflowConditionPojo, Object value) throws Exception {
        if (Objects.equals(workflowConditionPojo.getValueType(), WorkflowValueTypeEnum.FIXED_VALUE.getType())) {
            ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt();
            conditionsEntityExt.setSymbol(workflowConditionPojo.getSymbol());
            conditionsEntityExt.setValue(workflowConditionPojo.getValue());
            conditionsEntityExt.setFieldType(workflowConditionPojo.getFieldType());
            return compareValueByConditionHelp.compareValueByCondition(conditionsEntityExt, value);
        } else {
            return false;
        }
    }

    /**
     * baseHelp 这个类引不到,就复制过来了
     * 根据数据id，获取多条数据
     * @param dataIdList
     * @param businessType
     * @param saasMark
     * @param corpid
     * @return
     * @throws XbbException
     */
    @Deprecated
    public List<PaasFormDataEntityExt> getByDataIdList(Collection<Long> dataIdList, Integer businessType, Integer saasMark, Long formId, String corpid) {
        if (CollectionsUtil.isEmpty(dataIdList)) {
            return new ArrayList<>();
        }
        List<PaasFormDataEntityExt> formDataList = new ArrayList<>();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put(StringConstant.IDIN, dataIdList);
        param.put(StringConstant.FORM_ID, formId);
        try {
            if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
                XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
                switch (xbbRefTypeEnum) {
                    case CUSTOMER_MANAGEMENT:
                        List<CustomerEntityExt> customerList = customerModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(customerList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case CONTACT:
                        List<ContactEntityExt> contactList = contactModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(contactList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case CUSTOMER_COMMUNICATE:
                        List<CustomerCommunicateEntityExt> customerCommunicateList = customerCommunicateModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(customerCommunicateList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case COMMUNICATE_PLAN:
                        List<CommunicatePlanEntityExt> communicatePlanList = communicatePlanModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(communicatePlanList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case SALES_OPPORTUNITY:
                        List<OpportunityEntityExt> opportunityList = opportunityModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(opportunityList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case CONTRACT:
                        List<ContractEntityExt> contractList = contractModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(contractList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case REFUND:
                        List<RefundEntityExt> refundList = refundModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(refundList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case WORK_REPORT:
                    case WORKREPORT_WEEKLY:
                    case WORKREPORT_DAILY:
                    case WORKREPORT_MONTHLY:
                        List<WorkReportEntityExt> workReportList = workReportModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(workReportList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case SUPPLIER:
                        List<SupplierEntityExt> supplierList = supplierModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(supplierList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case SUPPLIER_CONTACT:
                        List<SupplierContactEntityExt> supplierContactList = supplierContactModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(supplierContactList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case SUPPLIER_COMMUNICATE:
                        List<SupplierCommunicateEntityExt> supplierCommunicateList = supplierCommunicateModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(supplierCommunicateList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case PURCHASE:
                        List<PurchaseEntityExt> purchaseList = purchaseModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(purchaseList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case RETURNED_PURCHASE:
                        List<ReturnedPurchaseEntityExt> returnedPurchaseList = returnedPurchaseModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(returnedPurchaseList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case BOM_BILL:
                        List<BomBillEntityExt> bomList = bomBillModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(bomList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case PRODUCTION_ORDER:
                        List<ProductionOrderEntityExt> productionOrderList = productionOrderModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(productionOrderList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case ASSEMBLE:
                        List<AssembleEntityExt> assembleList = assembleModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(assembleList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case INSTOCK:
                    case PURCHASE_INSTOCK:
                    case OTHER_INSTOCK:
                    case REFUND_INSTOCK:
                    case RETURNED_MATERIEL_INSTOCK:
                    case PRODUCTION_INSTOCK:
                        List<InstockEntityExt> instockList = instockModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(instockList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case OUTSTOCK:
                    case CONTRACT_OUTSTOCK:
                    case OTHER_OUTSTOCK:
                    case RETURNED_PURCHASE_OUTSTOCK:
                    case PRODUCTION_MATERIEL_OUTSTOCK:
                    case WORK_ORDER_OUTSTOCK:
                        List<OutstockEntityExt> outstockList = outstockModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(outstockList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case INVENTORY:
                        List<InventoryEntityExt> inventoryList = inventoryModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(inventoryList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case TRANSFER:
                        List<TransferEntityExt> transferList = transferModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(transferList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case WAREHOUSE:
                        List<WarehouseEntityExt> warehouseList = warehouseModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(warehouseList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case PAYMENT:
                        List<PaymentEntityExt> paymentList = paymentModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(paymentList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case PAY_PLAN:
                        List<PayPlanEntityExt> payPlanList = payPlanModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(payPlanList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case INVOICE:
                        List<InvoiceEntityExt> invoiceList = invoiceModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(invoiceList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case WORK_ORDER:
                        List<WorkOrderEntity> workOrderList = workOrderModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(workOrderList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case PAYMENT_SHEET:
                    case BAD_DEBT:
                    case WRITE_OFF_PREPAYMENT:
                    case RED_PAYMENT_SHEET:
                    case RED_WRITE_OFF_PREPAYMENT:
                    case RED_PREPAYMENT:
                    case PREPAYMENT:
                        List<PaymentSheetEntityExt> paymentSheetList = paymentSheetModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(paymentSheetList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case PAY_SHEET:
                    case PREPAY:
                    case WRITE_OFF_PREPAY:
                    case RED_WRITE_OFF_PAY:
                    case RED_WRITE_OFF_PREPAY:
                    case RED_PREPAY:
                    case BAD_PAY:
                        List<PayPlanSheetEntityExt> payPlanSheetList = payPlanSheetModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(payPlanSheetList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case PURCHASE_INVOICE:
                        List<PurchaseInvoiceEntityExt> purchaseInvoiceList = purchaseInvoiceModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(purchaseInvoiceList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case QUOTATION:
                        List<QuotationEntityExt> quotationList = quotationModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(quotationList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case CLUE:
                        List<ClueEntityExt> clueList = clueModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(clueList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case MARKET_ACTIVITY:
                        List<MarketActivityEntityExt> marketActivityList = marketActivityModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(marketActivityList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case FUND_TRANSFER:
                        List<FundTransferEntity> fundTransferEntities = fundTransferModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(fundTransferEntities, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case OTHER_INCOME:
                        List<OtherIncomeEntity> otherIncomeEntityList = otherIncomeModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(otherIncomeEntityList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case OTHER_EXPENSE:
                        List<OtherExpenseEntity> otherExpenseEntities = otherExpenseModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(otherExpenseEntities, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case COST_ADJUST:
                        List<CostAdjustEntityExt> costAdjustEntityExtList = costAdjustModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(costAdjustEntityExtList, formDataList, PaasFormDataEntityExt.class);
                        break;
                    case COMPETITOR:
                        List<CompetitorEntity> entitys = competitorModel.findEntitys(param);
                        BeanUtil.copyPropertiesList(entitys, formDataList, PaasFormDataEntityExt.class);
                        break;
                    default:
                        break;
                }
            } else {
                formDataList = paasFormDataModel.findEntitys(param);
            }
            if (Objects.isNull(formDataList)) {
                return new ArrayList<>();
            }
        } catch (Exception e) {
            log.error("getDataByDataIdList查询数据：", e);
        }
        return formDataList;
    }

    public void checkQueryResult(Object obj) throws XbbException {
        WorkflowValidateUtil.checkQueryResult(obj);
    }

    public void checkQueryResult(Object obj, String msg) throws XbbException {
        WorkflowValidateUtil.checkQueryResult(obj, msg);
    }

    public Map<Long, List<PaasFormDataEntityExt>> getWorkflowNodeDataMap(Set<Long> workflowNodeIdSet, WorkflowTransferPOJO workflowTransferPOJO) {
        Map<Long, List<PaasFormDataEntityExt>> workflowNodeDataMap = new HashMap<>(workflowNodeIdSet.size());
        PaasFormDataEntityExt paasFormDataEntityExt = WorkflowUtil.getFormData(workflowTransferPOJO);
        List<PaasFormDataEntityExt> list = new ArrayList<>();
        list.add(paasFormDataEntityExt);
        workflowNodeDataMap.put(workflowTransferPOJO.getData().getNodeId(), list);
        if (Objects.isNull(workflowTransferPOJO.getFlowDatas())) {
            return workflowNodeDataMap;
        }
        workflowNodeIdSet.remove(workflowTransferPOJO.getData().getNodeId());
        if (CollectionUtils.isEmpty(workflowNodeIdSet)) {
            return workflowNodeDataMap;
        }
        if (CollectionUtils.isNotEmpty(workflowNodeIdSet)) {
            workflowNodeIdSet.forEach(item -> {
                FlowData flowData = workflowTransferPOJO.getFlowDatas().getNodeIdMap().get(item.toString());
                if (Objects.nonNull(flowData)) {
                    List<Long> ids = flowData.getIds();
                    if (CollectionsUtil.isNotEmpty(ids)) {
                        //查询主表数据
                        List<PaasFormDataEntityExt> dataIdList = formDataHelp.getByDataIdList(ids,
                                flowData.getBusinessType(), flowData.getSaasMark(), flowData.getFormId(), workflowTransferPOJO.getCorpid());
                        workflowNodeDataMap.put(item, dataIdList);
                    }
                }
            });
        }
        return workflowNodeDataMap;
    }

    /**
     * 当用户未设置标题时，默认以{提交人}的{触发表单}审批
     * 举例：{提交人}为马雄   {触发表单}为合同订单
     * 审批标题为：马雄的合同订单审批
     *
     * @param workflowTransferPojo
     * @return
     * @throws XbbException
     */
    public String getDefaultTitle(WorkflowTransferPOJO workflowTransferPojo) throws XbbException {
        String commitUserName = workflowTransferPojo.getUser().getName();
        Long formId = workflowTransferPojo.getData().getFormId();
        Integer businessType = workflowTransferPojo.getData().getBusinessType();
        Integer subBusinessType = workflowTransferPojo.getData().getSubBusinessType();
        PaasFormEntity paasFormEntity = proFormHelp.getPaasForm(formId, businessType, workflowTransferPojo.getCorpid());

        String name = getFormNameForSpecial(businessType, subBusinessType, paasFormEntity);
        return commitUserName + I18nMessageUtil.getMessage(CommonConstant.OF) + name + I18nMessageUtil.getMessage(I18nStringConstant.APPROVAL);
    }

    private String getFormNameForSpecial(Integer businessType, Integer subBusinessType, PaasFormEntity paasFormEntity) {
        String name = paasFormEntity.getName();
        SheetTypeEnum sheetTypeEnum;
        if (Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode()) && Objects.nonNull(subBusinessType)) {
            PaymentSheetTypeEnum paymentSheetTypeEnum = PaymentSheetTypeEnum.getByBusinessType(subBusinessType);
            sheetTypeEnum = paymentSheetTypeEnum.getSheetTypeEnum();
            name = sheetTypeEnum.getFormName();
        } else if (Objects.equals(businessType, XbbRefTypeEnum.PAY_SHEET.getCode()) && Objects.nonNull(subBusinessType)) {
            PaySheetTypeEnum paySheetTypeEnum = PaySheetTypeEnum.getByBusinessType(subBusinessType);
            sheetTypeEnum = paySheetTypeEnum.getSheetTypeEnum();
            name = sheetTypeEnum.getFormName();
        }
        return name;
    }

    /**
     * 获取消息内容等信息
     *
     * @param messageContent
     * @param formExplainMap
     * @param workOrderFormExplainMap
     * @param workflowTransferPOJO
     * @param workflowNodeDataMap
     * @return
     * @throws XbbException
     */
    public String getContentValue(List<WorkflowTitlePojo> messageContent, Map<Long, Map<String, FieldAttrEntity>> formExplainMap,
                                  Map<Long, Map<String, FieldAttrEntity>> workOrderFormExplainMap, WorkflowTransferPOJO workflowTransferPOJO, Map<Long, List<PaasFormDataEntityExt>> workflowNodeDataMap) throws XbbException {
        StringBuilder stringBuilder = new StringBuilder();
        if (CollectionUtils.isEmpty(messageContent)) {
            return stringBuilder.toString();
        }
        for (WorkflowTitlePojo pojo : messageContent) {
            //系统字段
            if (Objects.equals(1, pojo.getSystem())) {
                if (Objects.equals(pojo.getProperty(), WorkflowSystemFieldEnum.COMMIT_USER.getProperty())) {
                    String commitUserName = workflowTransferPOJO.getUser().getName();
                    stringBuilder.append(commitUserName);
                } else if (Objects.equals(pojo.getProperty(), WorkflowSystemFieldEnum.TRIGGER_FORM.getProperty())) {
                    Long formId = workflowTransferPOJO.getData().getFormId();
                    Integer businessType = workflowTransferPOJO.getData().getBusinessType();
                    PaasFormEntity paasFormEntity = proFormHelp.getPaasForm(formId, businessType, workflowTransferPOJO.getCorpid());
                    String name = getFormNameForSpecial(businessType, workflowTransferPOJO.getData().getSubBusinessType(), paasFormEntity);
                    stringBuilder.append(name);
                }
            } else {
                //自定义字段
                if (StringUtil.isEmpty(pojo.getAttr())) {
                    stringBuilder.append(pojo.getContent());
                    continue;
                }
                Map<String, FieldAttrEntity> explainMap = formExplainMap.get(pojo.getFormId());
                if (Objects.equals(pojo.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                    explainMap = workOrderFormExplainMap.get(pojo.getFormId());
                }
                FieldAttrEntity fieldAttrEntity = explainMap.get(pojo.getAttr());
                if (Objects.isNull(fieldAttrEntity)) {
                    continue;
                }
                //触发表单
                if (Objects.equals(pojo.getTriggerNodeFlag(), BasicConstant.ONE)) {
                    //从触发数据data
                    PaasFormDataEntityExt paasFormDataEntityExt = WorkflowUtil.getFormData(workflowTransferPOJO);
                    FieldAnalyseService fieldAnalyseService = fieldAnalyseMap.get(fieldAttrEntity.getFieldType());
                    Object value = fieldAnalyseService.analysisData(pojo.getFormId(), pojo.getBusinessType(), pojo.getSaasMark(), paasFormDataEntityExt, paasFormDataEntityExt.getData(), fieldAttrEntity);
                    if (Objects.nonNull(value)) {
                        stringBuilder.append(value);
                    }
                } else {
                    //查询主表数据
                    List<PaasFormDataEntityExt> formDataList = workflowNodeDataMap.get(pojo.getWorkflowNodeId());
                    if (CollectionUtils.isNotEmpty(formDataList)) {
                        for (PaasFormDataEntityExt item : formDataList) {
                            FieldAnalyseService fieldAnalyseService = fieldAnalyseMap.get(fieldAttrEntity.getFieldType());
                            Object value = fieldAnalyseService.analysisData(pojo.getFormId(), pojo.getBusinessType(), pojo.getSaasMark(), item, item.getData(), fieldAttrEntity);
                            if (Objects.nonNull(value)) {
                                stringBuilder.append(value);
                            }
                        }
                    }
                }
            }

        }
        return stringBuilder.toString();
    }

    /**
     * 获取消息内容等信息
     *
     * @param messageContent
     * @param formExplainMap
     * @param workOrderFormExplainMap
     * @param workflowTransferPOJO
     * @param workflowNodeDataMap
     * @return
     * @throws XbbException
     */
    public String getTitleValue(List<WorkflowTitlePojo> messageContent, Map<Long, Map<String, FieldAttrEntity>> formExplainMap,
                                Map<Long, Map<String, FieldAttrEntity>> workOrderFormExplainMap, WorkflowTransferPOJO workflowTransferPOJO,
                                Map<Long, List<PaasFormDataEntityExt>> workflowNodeDataMap, Integer titleMax) throws XbbException {
        StringBuilder stringBuilder = new StringBuilder();
        if (CollectionUtils.isEmpty(messageContent)) {
            return stringBuilder.toString();
        }
        String title = getContentValue(messageContent, formExplainMap, workOrderFormExplainMap, workflowTransferPOJO, workflowNodeDataMap);
        if (title.length() > titleMax) {
            return title.substring(0, titleMax);
        }
        return title;
    }

    public boolean getEditAfterFinished(String corpid, Long formId, Integer businessType, Integer saasMark, UserVO loginUser) {
        // 获取流程设置审批后是否可编辑
        boolean isAdminOrBoss = loginUser.isAdminOrBoss();
        if (isAdminOrBoss) {
            // 老板和管理员审批通过以后总是允许编辑
            return true;
        }
        Integer allowEditAfterFinished = 0;
        String alias = RedisPrefixConstant.ALLOW_EDIT_AFTER_FINISHED;
        FormConfigEntity formConfigEntity = formConfigModel.getByConfig(alias, corpid, formId, saasMark, businessType);
        if (Objects.nonNull(formConfigEntity)) {
            allowEditAfterFinished = Integer.valueOf(formConfigEntity.getConfigValue());
        }
        return allowEditAfterFinished == 1;
    }

    /**
     * 一些特殊业务的业务类型需要做特殊处理，比如红冲回款单、坏账回款单要变成回款单类型
     *
     * @param businessType 业务类型
     * @return
     */
    public Integer getSpecialBusinessType(Integer businessType) {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum) {
            case PAYMENT_SHEET:
            case WRITE_OFF_PREPAYMENT:
            case PREPAYMENT:
            case RED_PREPAYMENT:
            case RED_PAYMENT_SHEET:
            case RED_WRITE_OFF_PREPAYMENT:
            case RED_WRITE_OFF_BALANCE:
            case BAD_DEBT:
                businessType = XbbRefTypeEnum.PAYMENT_SHEET.getCode();
                break;
            case PAY_SHEET:
            case WRITE_OFF_PREPAY:
            case RED_WRITE_OFF_PAY:
            case RED_WRITE_OFF_PREPAY:
            case PREPAY:
            case RED_PREPAY:
            case BAD_PAY:
                businessType = XbbRefTypeEnum.PAY_SHEET.getCode();
                break;
            case OTHER_INCOME:
            case RED_OTHER_INCOME:
                businessType = XbbRefTypeEnum.OTHER_INCOME.getCode();
                break;
            case OTHER_EXPENSE:
            case RED_OTHER_EXPENSE:
                businessType = XbbRefTypeEnum.OTHER_EXPENSE.getCode();
                break;
            default:
        }
        return businessType;
    }

    /**
     *
     * @Description: 获取节点，不计算条件块节点,用于计算工作流节点数量是否超过上限
     * @param
     * @return: java.lang.Integer
     * @Author: shen.yang
     * @Date: 2022/5/20  10:51
     */
    public Integer getNodeCount(String corpid, Long workflowId){
        //查询工作流的所有节点,条件块节点不纳入计算
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(ParameterConstant.CORPID,corpid);
        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        params.put("workflowId",workflowId);
        params.put("typeNotIn",Collections.singletonList(WorkflowNodeTypeEnum.CONDITION_BLOCK_NODE.getType()));
        List<WorkflowNodeEntity> oldWorkFlowNodeList = workflowNodeModel.findEntitys(params);
        return oldWorkFlowNodeList.size();
    }

    /**
     *
     * @Description: 重写了获取流程节点日志   原方法见com.xbongbong.workflow.service.approveListPage.impl.WorkflowApproveListPageOperationServiceImpl#getProcessNodeTaskLogList
     * @param nodeTaskList
     * @param userMap
     * @param workflowNodeTaskGetDTO
     * @return: com.xbongbong.workflow.pojo.vo.WorkflowNodeTaskGetVO
     * @Author: shen.yang
     * @Date: 2022/8/8  19:09
    */
    public WorkflowNodeTaskGetVO getProcessNodeTaskLogList(List<WorkflowTaskNodeEntityExt> nodeTaskList, Map<String, UserEntity> userMap, WorkflowNodeTaskGetDTO workflowNodeTaskGetDTO) throws XbbException {
        WorkflowNodeTaskGetVO workflowNodeTaskGetVO = new WorkflowNodeTaskGetVO();

        //获取人工节点日志
        ProcessNodeTaskLogMidPojo artificialNodeLogList = getArtificialNodeLogList(nodeTaskList, userMap, workflowNodeTaskGetDTO);
        workflowNodeTaskGetVO.setCcUserList(artificialNodeLogList.getCcUserList());
        List<Object> logList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(artificialNodeLogList.getNodeTaskLogList())){
            logList.addAll(artificialNodeLogList.getNodeTaskLogList());
        }

        //获取评论日志
        List<WorkflowCommentEntityExt> commentNodeLogList = getCommentNodeLogList(workflowNodeTaskGetDTO);
        if(CollectionUtils.isNotEmpty(commentNodeLogList)){
            logList.addAll(commentNodeLogList);
        }

        //排序
        bubbleSort(logList);

        //未处理节点强制放第一个
        sortUntreatedObject(logList);
        workflowNodeTaskGetVO.setCurrentLog(logList);
        return workflowNodeTaskGetVO;
    }
    /**
     *
     * @Description: 获取当前审批的人工节点日志，抄送和审批节点
     * @param nodeTaskList
     * @param userMap
     * @param workflowNodeTaskGetDTO
     * @return: com.xbongbong.paas.pojo.ProcessNodeTaskLogMidPojo
     * @Author: shen.yang
     * @Date: 2022/8/16  15:55
    */
    public ProcessNodeTaskLogMidPojo getArtificialNodeLogList(List<WorkflowTaskNodeEntityExt> nodeTaskList, Map<String, UserEntity> userMap, WorkflowNodeTaskGetDTO workflowNodeTaskGetDTO) throws XbbException {
        ProcessNodeTaskLogMidPojo processNodeTaskLogMidPojo = new ProcessNodeTaskLogMidPojo();
        List<ProcessNodeTaskLogPoJo> processNodeTaskPojoList = new ArrayList<>();
        List<UserEntity> ccUserList = new ArrayList<>();
        Iterator<WorkflowTaskNodeEntityExt> iterator = nodeTaskList.iterator();
        WorkflowTaskNodeEntityExt lastNodeEntity = new WorkflowTaskNodeEntityExt();
        //当前节点
        WorkflowTaskNodeEntityExt currentNodeTask = null;
        Set<Long> workflowNodeSet = nodeTaskList.stream().map(WorkflowTaskNodeEntityExt::getWorkflowNodeId).collect(Collectors.toSet());
        List<WorkflowNodeEntity> workflowNodeEntityList = workflowNodeModel.getByIdIn(workflowNodeSet, workflowNodeTaskGetDTO.getCorpid());
        Map<Long, WorkflowNodeEntity> workflowNodeEntityMap = workflowNodeEntityList.stream().collect(Collectors.toMap(WorkflowNodeEntity::getId, t -> t));
        for (WorkflowTaskNodeEntityExt entityExt : nodeTaskList) {
            if (Objects.equals(entityExt.getId(), workflowNodeTaskGetDTO.getProcessNodeTaskId())) {
                currentNodeTask = entityExt;
                break;
            }
        }
        if (Objects.isNull(currentNodeTask)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_NOT_EXIST);
        }
        while (iterator.hasNext()){
            WorkflowTaskNodeEntityExt taskNodeEntity = iterator.next();
            //其他人通过的直接跳过
            if(Objects.equals(taskNodeEntity.getTaskType(), TaskTypeEnum.OTHER_COMMIT.getType())){
                continue;
            }
            //审批节点的已抄送直接跳过
            if(Objects.equals(taskNodeEntity.getNodeType(), NodeTypeEnum.PROCESS_NODE.getNodeType()) && Objects.equals(taskNodeEntity.getTaskType(), TaskTypeEnum.CC.getType())){
                continue;
            }

            // 当前节点的抄送人
            if (Objects.equals(taskNodeEntity.getWorkflowNodeId(), currentNodeTask.getWorkflowNodeId()) && Objects.equals(taskNodeEntity.getTaskType(), TaskTypeEnum.WAIT_CC.getType())){
                // 抄送人
                if (userMap.containsKey(taskNodeEntity.getUserId())) {
                    ccUserList.add(userMap.get(taskNodeEntity.getUserId()));
                }
                continue;
            } else if (taskNodeEntity.getTaskType().equals(TaskTypeEnum.WAIT_CC.getType())) {
                continue;
            }
            if(CollectionUtils.isEmpty(processNodeTaskPojoList)){
                ProcessNodeTaskLogPoJo processNodeTaskLog = getProcessNodeTaskLog(taskNodeEntity, userMap, workflowNodeTaskGetDTO);
                processNodeTaskPojoList.add(processNodeTaskLog);
                lastNodeEntity = taskNodeEntity;
            }else{
                if(!Objects.equals(taskNodeEntity.getWorkflowNodeId(), lastNodeEntity.getWorkflowNodeId())){
                    if(Objects.equals(taskNodeEntity.getTaskType(), TaskTypeEnum.UNTREATED.getType())){
                        ProcessNodeTaskLogPoJo processNodeTaskLog = getProcessNodeTaskLog(taskNodeEntity, userMap, workflowNodeTaskGetDTO);
                        ProcessNodeTaskLogPoJo nodeTaskLogPoJo = formatProcessNodeTaskLogPoJo(processNodeTaskLog);
                        List<ProcessNodeTaskLogPoJo> logPojoList = new ArrayList<>();
                        logPojoList.add(processNodeTaskLog);
                        nodeTaskLogPoJo.setUnCommitNodeTaskList(logPojoList);
                        processNodeTaskPojoList.add(nodeTaskLogPoJo);
                    }else{
                        ProcessNodeTaskLogPoJo processNodeTaskLog = getProcessNodeTaskLog(taskNodeEntity, userMap, workflowNodeTaskGetDTO);
                        processNodeTaskPojoList.add(processNodeTaskLog);
                    }
                    //单审批人的转交节点要放到主线里展示，不能合并展示
                    if(processNodeTaskPojoList.size() > 2){
                        ProcessNodeTaskLogPoJo logPoJo = processNodeTaskPojoList.get(processNodeTaskPojoList.size() - 2);
                        List<ProcessNodeTaskLogPoJo> unCommitNodeTaskList = logPoJo.getUnCommitNodeTaskList();
                        if(CollectionUtils.isNotEmpty(unCommitNodeTaskList) && unCommitNodeTaskList.size() == 2 && Objects.equals(unCommitNodeTaskList.get(0).getTaskType(), TaskTypeEnum.TRANSFER.getType())){
                            logPoJo.setUnCommitNodeTaskList(null);
                            processNodeTaskPojoList.add(unCommitNodeTaskList.get(1));
                        }
                    }
                }else{
                    //需要合并
                    ProcessNodeTaskLogPoJo logPoJo = processNodeTaskPojoList.get(processNodeTaskPojoList.size() - 1);
                    if(Objects.equals(logPoJo.getNodeType(), NodeTypeEnum.CC_PROCESS_NODE.getNodeType())){
                        //抄送节点合并要修改主节点的属性
                        logPoJo.setSignType(SignTypeEnum.MULTI_CC.getValue());
                        logPoJo.setSignTypeDesc(SignTypeEnum.getSignTypeEnum(SignTypeEnum.MULTI_CC.getValue()));
                    }
                    List<ProcessNodeTaskLogPoJo> unCommitNodeTaskList = logPoJo.getUnCommitNodeTaskList();
                    if(CollectionUtils.isEmpty(unCommitNodeTaskList)){
                        ProcessNodeTaskLogPoJo nodeTaskLogPoJo = formatProcessNodeTaskLogPoJo(logPoJo);
                        unCommitNodeTaskList = new ArrayList<>();
                        unCommitNodeTaskList.add(logPoJo);
                        unCommitNodeTaskList.add(getProcessNodeTaskLog(taskNodeEntity, userMap, workflowNodeTaskGetDTO));
                        nodeTaskLogPoJo.setUnCommitNodeTaskList(unCommitNodeTaskList);
                        processNodeTaskPojoList.removeIf(v -> Objects.equals(v.getId(), logPoJo.getId()));
                        processNodeTaskPojoList.add(nodeTaskLogPoJo);
                    }else{
                        unCommitNodeTaskList.add(getProcessNodeTaskLog(taskNodeEntity, userMap, workflowNodeTaskGetDTO));
                    }
                }
                lastNodeEntity = taskNodeEntity;
            }
        }
        //单审批人的转交节点要放到主线里展示，不能合并展示
        ProcessNodeTaskLogPoJo logPoJo = processNodeTaskPojoList.get(processNodeTaskPojoList.size() - 1);
        List<ProcessNodeTaskLogPoJo> unCommitNodeTaskList = logPoJo.getUnCommitNodeTaskList();
        if(CollectionUtils.isNotEmpty(unCommitNodeTaskList) && unCommitNodeTaskList.size() == 2 && Objects.equals(unCommitNodeTaskList.get(0).getTaskType(), TaskTypeEnum.TRANSFER.getType())){
            logPoJo.setUnCommitNodeTaskList(new ArrayList<>());
            ProcessNodeTaskLogPoJo processNodeTaskLogPoJo = unCommitNodeTaskList.get(1);
            if(Objects.equals(processNodeTaskLogPoJo.getTaskType(), TaskTypeEnum.UNTREATED.getType())){
                ProcessNodeTaskLogPoJo unCommit = formatProcessNodeTaskLogPoJo(processNodeTaskLogPoJo);
                unCommit.setUnCommitNodeTaskList(Collections.singletonList(processNodeTaskLogPoJo));
                processNodeTaskPojoList.add(unCommit);
            }else{
                processNodeTaskPojoList.add(processNodeTaskLogPoJo);
            }
        }
        addTaskNodeName(processNodeTaskPojoList, workflowNodeEntityMap);
        processNodeTaskLogMidPojo.setNodeTaskLogList(processNodeTaskPojoList);
        processNodeTaskLogMidPojo.setCcUserList(ccUserList);
        return processNodeTaskLogMidPojo;
    }

    /**
     *
     * @Description: 获取当前审批的评论节点日志
     * @param workflowNodeTaskGetDTO
     * @return: java.util.List<com.xbongbong.workflow.domain.entity.ext.WorkflowCommentEntityExt>
     * @Author: shen.yang
     * @Date: 2022/8/16  15:56
    */
    private List<WorkflowCommentEntityExt> getCommentNodeLogList(WorkflowNodeTaskGetDTO workflowNodeTaskGetDTO) throws XbbException{
        WorkflowCommentListDTO commentListDTO = new WorkflowCommentListDTO();
        commentListDTO.setCorpid(workflowNodeTaskGetDTO.getCorpid());
        commentListDTO.setAppId(workflowNodeTaskGetDTO.getAppId());
        commentListDTO.setRefId(workflowNodeTaskGetDTO.getProcessTaskId());
        commentListDTO.setUserId(workflowNodeTaskGetDTO.getUserId());
        commentListDTO.setLoginUser(workflowNodeTaskGetDTO.getLoginUser());
        // 审批评论类型
        commentListDTO.setBusinessType(BusinessCommentEnum.APPROVAL.getBusinessType());
        WorkflowCommentListVO commentListVO = workflowCommentService.list(commentListDTO);
        if (commentListVO == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        List<WorkflowCommentEntityExt> commentList = commentListVO.getList();
        if (CollectionUtils.isNotEmpty(commentList)) {
            for (WorkflowCommentEntityExt item : commentList) {
                if (Objects.equals(item.getUserId(), workflowNodeTaskGetDTO.getUserId())) {
                    item.setUserName(I18nMessageUtil.getMessage(CommonConstant.ME));
                }
            }
        }
        return commentList;
    }



    /**
     * 增加节点名称返回
     * @param logList 审批日志
     * @param workflowNodeEntityMap 工作流模板节点信息
     */
    private void addTaskNodeName(List<ProcessNodeTaskLogPoJo> logList, Map<Long, WorkflowNodeEntity> workflowNodeEntityMap) {
        for (ProcessNodeTaskLogPoJo processNodeTaskLogPoJo : logList) {
            // 判断是否是未审批
            if (TaskTypeEnum.UNTREATED.getType().equals(processNodeTaskLogPoJo.getTaskType())) {
                // 未审批从UnCommitNodeTaskList只拿第一个id
                List<ProcessNodeTaskLogPoJo> unCommitNodeTaskList = processNodeTaskLogPoJo.getUnCommitNodeTaskList();
                Long unCommiteTemplateNodeId = unCommitNodeTaskList.get(0).getTemplateNodeId();
                if (workflowNodeEntityMap.containsKey(unCommiteTemplateNodeId)) {
                    processNodeTaskLogPoJo.setTemplateNodeName(workflowNodeEntityMap.get(unCommiteTemplateNodeId).getName());
                    // 当下面这种情况时，前端渲染数据从unCommitNodeTaskList中获取，所以要往这里多放一个节点名
                    if (NodeTypeEnum.PROCESS_NODE.getNodeType().equals(processNodeTaskLogPoJo.getNodeType()) && Objects.equals(unCommitNodeTaskList.size(), 1)) {
                        unCommitNodeTaskList.get(0).setTemplateNodeName(workflowNodeEntityMap.get(unCommiteTemplateNodeId).getName());
                    }
                }
            } else if (workflowNodeEntityMap.containsKey(processNodeTaskLogPoJo.getTemplateNodeId())) {
                processNodeTaskLogPoJo.setTemplateNodeName(workflowNodeEntityMap.get(processNodeTaskLogPoJo.getTemplateNodeId()).getName());
            }
        }
    }


    /**
     * 封装流程日志对象
     *
     * @param item
     * @param userMap
     * @return
     */
    private ProcessNodeTaskLogPoJo getProcessNodeTaskLog(WorkflowTaskNodeEntityExt item, Map<String, UserEntity> userMap, WorkflowNodeTaskGetDTO workflowNodeTaskGetDTO) throws XbbException {
        ProcessNodeTaskLogPoJo processNodeTaskLogPoJo = new ProcessNodeTaskLogPoJo();
        try {
            //BeanUtil.copyProperties(item, processNodeTaskLogPoJo);
            processNodeTaskLogPoJo.setId(item.getId());
            processNodeTaskLogPoJo.setSignType(item.getSignType());
            processNodeTaskLogPoJo.setTaskType(item.getTaskType());
            processNodeTaskLogPoJo.setNodeType(item.getNodeType());
            processNodeTaskLogPoJo.setOpinion(item.getOpinion());
            processNodeTaskLogPoJo.setAddTime(item.getAddTime());
            processNodeTaskLogPoJo.setUpdateTime(item.getUpdateTime());

            processNodeTaskLogPoJo.setTemplateNodeId(item.getWorkflowNodeId());
            // 会签或签描述字段
            processNodeTaskLogPoJo.setSignTypeDesc(SignTypeEnum.getSignTypeEnum(item.getSignType()));
            // 审批图片
            if (StringUtil.isNotEmpty(item.getImages())) {
                processNodeTaskLogPoJo.setImages(JsonHelperUtil.parseArray(item.getImages(), String.class));
            }
            // 审批附件
            if (StringUtil.isNotEmpty(item.getAttachment())) {
                List<String> attachmentStrList = JsonHelperUtil.parseArray(item.getAttachment(), String.class);
                List<PaasAttachmentEntityExt> attachmentList = new ArrayList<>();
                attachmentStrList.forEach((attachmentItem) -> {
                    PaasAttachmentEntityExt attachment = JSONObject.parseObject(attachmentItem, PaasAttachmentEntityExt.class);
                    attachmentList.add(attachment);
                });
                processNodeTaskLogPoJo.setAttachmentList(attachmentList);
            }
            // 开始节点描述
            if (item.getNodeType().equals(NodeTypeEnum.START_PROCESS_NODE.getNodeType())) {
                processNodeTaskLogPoJo.setStartNodeDesc(I18nMessageUtil.getMessage(PaasConstant.INITIATE_AN_APPLICATION));
                if (Objects.equals(item.getTaskType(), TaskTypeEnum.REVOKE.getType())) {
                    processNodeTaskLogPoJo.setStartNodeDesc(I18nMessageUtil.getMessage(PaasConstant.REVOKE_PROCESS));
                } else if (Objects.equals(item.getTaskType(), TaskTypeEnum.AGAIN_COMMIT.getType())) {
                    processNodeTaskLogPoJo.setStartNodeDesc(TaskTypeEnum.AGAIN_COMMIT.getStatusMemo());
                }
            } else {
                processNodeTaskLogPoJo.setStartNodeDesc("");
            }
            processNodeTaskLogPoJo.setOperatorUser(userMap.get(item.getUserId()));
            // 判断负责人是否为当前登录用户
            UserEntity userEntity = processNodeTaskLogPoJo.getOperatorUser();
            processNodeTaskLogPoJo.setTaskTypeDesc(TaskTypeEnum.getStatusMemo(item.getTaskType()));
            if (userEntity != null && workflowNodeTaskGetDTO.getUserId().equals(userEntity.getUserId())) {
                processNodeTaskLogPoJo.setIsMe(1);
                processNodeTaskLogPoJo.setIsMeDesc(I18nMessageUtil.getMessage(CommonConstant.ME));
                if (item.getTaskType().equals(TaskTypeEnum.UNTREATED.getType())) {
                    processNodeTaskLogPoJo.setTaskTypeDesc(I18nMessageUtil.getMessage(PaasConstant.WAITING_FOR_ME_TO_APPROVE));
                }
            } else {
                processNodeTaskLogPoJo.setIsMe(0);
                processNodeTaskLogPoJo.setIsMeDesc("");
                if(Objects.equals(PaasConstant.SYS_USER_ID, item.getUserId())) {
                    processNodeTaskLogPoJo.setIsMeDesc(I18nMessageUtil.getMessage(CommonConstant.SYSTEM));
                    processNodeTaskLogPoJo.setOpinion(I18nMessageUtil.getMessage(I18nStringConstant.CURRENT_NODE_APPROVER_EMPTY));
                    // 系统管理员
                    UserEntity systemUser = new UserEntity();
                    systemUser.setUserId(item.getUserId());
                    systemUser.setRoleIds("|1|2|3|23|");
                    systemUser.setCorpid(item.getCorpid());
                    systemUser.setAvatar("");
                    systemUser.setName(I18nMessageUtil.getMessage(CommonConstant.SYSTEM));
                    processNodeTaskLogPoJo.setOperatorUser(systemUser);
                }
            }
            // 转交人
            if (StringUtil.isNotEmpty(item.getTransferUserId())) {
                processNodeTaskLogPoJo.setTransferUser(userMap.get(item.getTransferUserId()));
            }
            // 撤回操作人
            if (StringUtil.isNotEmpty(item.getRevokeUserId())) {
                processNodeTaskLogPoJo.setRevokeUser(userMap.get(item.getRevokeUserId()));
            }
            // 回退人
            /*if (item.getBackspaceNode() != null && item.getBackspaceNode() != 0) {
                ProcessNodeTaskGetDTO result = new ProcessNodeTaskGetDTO();
                BeanUtil.copyProperties(processNodeTaskGetDTO, result);
                Map<Long, PaasworkflowNodeEntityExt> nodeMap = getNodeMap(processNodeTaskGetDTO);
                processNodeTaskLogPoJo.setBackNodeName(nodeMap.get(item.getBackspaceNode()).getName());
            }*/
            // 加签
            if (Objects.nonNull(item.getAddSignature())) {
                if (Objects.equals(item.getAddSignature(), BasicConstant.ONE)) {
                    processNodeTaskLogPoJo.setIsAddSign(BasicConstant.ONE);
                } else {
                    processNodeTaskLogPoJo.setIsAddSign(BasicConstant.ZERO);
                }
            }
        } catch (Exception e) {
            log.error("工作流获取流程日志对象出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return processNodeTaskLogPoJo;
    }



    private ProcessNodeTaskLogPoJo formatProcessNodeTaskLogPoJo(ProcessNodeTaskLogPoJo pojo){
        ProcessNodeTaskLogPoJo logPojo = new ProcessNodeTaskLogPoJo();
        logPojo.setAddTime(pojo.getAddTime());
        logPojo.setId(pojo.getId());
        logPojo.setIsAddSign(pojo.getIsAddSign());
        logPojo.setIsMe(pojo.getIsMe());
        logPojo.setIsMeDesc(pojo.getIsMeDesc());
        logPojo.setNodeType(pojo.getNodeType());
        logPojo.setOperatorUser(pojo.getOperatorUser());
        logPojo.setOpinion(pojo.getOpinion());
        logPojo.setSignType(pojo.getSignType());
        logPojo.setSignTypeDesc(pojo.getSignTypeDesc());
        logPojo.setStartNodeDesc(pojo.getStartNodeDesc());
        logPojo.setTaskType(pojo.getTaskType());
        logPojo.setTaskTypeDesc(pojo.getTaskTypeDesc());
        logPojo.setTemplateNodeId(pojo.getTemplateNodeId());
        logPojo.setUpdateTime(pojo.getUpdateTime());
        logPojo.setTransferUser(pojo.getTransferUser());
        logPojo.setImages(pojo.getImages());
        logPojo.setAttachmentList(pojo.getAttachmentList());
        return logPojo;
    }



    /**
     * 冒泡排序  按照时间排序，如果时间一样，按照id排序
     *
     * @param list
     */
    private static void bubbleSort(List<Object> list) {
        int len = list.size();
        for (int i = 0; i < len - 1; i++) {
            for (int j = 0; j < len - 1 - i; j++) {
                long addTimeLeft = 0L;
                long addTimeMid = 0L;
                long idLeft = 0L;
                long idMid = 0L;
                //long typeLeft = 0L;
                //long typeMid = 0L;
                if (list.get(j) instanceof ProcessNodeTaskLogPoJo) {
                    ProcessNodeTaskLogPoJo processNodeTaskLogPoJo = (ProcessNodeTaskLogPoJo) list.get(j);
                    addTimeLeft = processNodeTaskLogPoJo.getUpdateTime();
                    idLeft = processNodeTaskLogPoJo.getId();
                }
                if (list.get(j) instanceof WorkflowCommentEntityExt) {
                    WorkflowCommentEntityExt paasCommentEntityExt = (WorkflowCommentEntityExt) list.get(j);
                    addTimeLeft = paasCommentEntityExt.getUpdateTime();
                    idLeft = paasCommentEntityExt.getId();
                }
                if (list.get(j + 1) instanceof ProcessNodeTaskLogPoJo) {
                    ProcessNodeTaskLogPoJo processNodeTaskLogPoJo = (ProcessNodeTaskLogPoJo) list.get(j + 1);
                    addTimeMid = processNodeTaskLogPoJo.getUpdateTime();
                    idMid = processNodeTaskLogPoJo.getId();
                }
                if (list.get(j + 1) instanceof WorkflowCommentEntityExt) {
                    WorkflowCommentEntityExt paasCommentEntityExt = (WorkflowCommentEntityExt) list.get(j + 1);
                    addTimeMid = paasCommentEntityExt.getUpdateTime();
                    idMid = paasCommentEntityExt.getId();
                }
                // 相邻元素两两对比
                if (addTimeLeft == addTimeMid) {
                    //if(typeLeft == typeMid){
                    if (idLeft > idMid) {
                        elementExchange(j, list);
                    }
                    //}else if(typeLeft < typeMid){
                    //elementExchange(j, list);
                    //}
                } else if (addTimeLeft > addTimeMid) {
                    elementExchange(j, list);
                }
            }
        }
    }

    private static void elementExchange(int j, List<Object> list) {
        // 元素交换
        Object temp = list.get(j + 1);
        list.set(j + 1, list.get(j));
        list.set(j, temp);
    }


    /**
     * 强行将未处理的节点放到最后
     * @param currentLogList
     */
    private void sortUntreatedObject(List<Object> currentLogList) {
        List<Object> untreatedList = new ArrayList<>();
        Iterator<Object> iterator = currentLogList.iterator();
        while (iterator.hasNext()) {
            Object object = iterator.next();
            if (object instanceof ProcessNodeTaskLogPoJo) {
                ProcessNodeTaskLogPoJo processNodeTaskLogPoJo = (ProcessNodeTaskLogPoJo) object;
                if (Objects.equals(processNodeTaskLogPoJo.getTaskType(), TaskTypeEnum.UNTREATED.getType())) {
                    untreatedList.add(object);
                    iterator.remove();
                }
            }
        }
        currentLogList.addAll(untreatedList);
    }


}